package com.roads.supervisor.service.impl;

import com.roads.common.constant.Constants;
import com.roads.common.utils.StringUtils;
import com.roads.project.domain.ProInstitution;
import com.roads.project.domain.ProInstitutionDetail;
import com.roads.project.domain.ProSupervisorItems;
import com.roads.project.mapper.ProInstitutionDetailMapper;
import com.roads.project.mapper.ProInstitutionMapper;
import com.roads.project.mapper.ProSupervisorItemsMapper;
import com.roads.supervisor.constant.PaymentConstant;
import com.roads.supervisor.domain.SupBoq;
import com.roads.supervisor.domain.SupMeterageDetailConstruction;
import com.roads.supervisor.domain.SupMeterageDetailDefect;
import com.roads.supervisor.domain.SupMeterageDetailOther;
import com.roads.supervisor.domain.SupMeterageDetailWinter;
import com.roads.supervisor.domain.SupPeriod;
import com.roads.supervisor.domain.summary.SupSummaryBoq;
import com.roads.supervisor.domain.summary.SupSummaryIpc;
import com.roads.supervisor.domain.summary.SupSummaryRecord;
import com.roads.supervisor.domain.summary.SupSummaryRecordUserVo;
import com.roads.supervisor.domain.summary.SupSummaryVo;
import com.roads.supervisor.mapper.SupBoqMapper;
import com.roads.supervisor.mapper.SupMeterageDetailConstructionMapper;
import com.roads.supervisor.mapper.SupMeterageDetailDefectMapper;
import com.roads.supervisor.mapper.SupMeterageDetailOtherMapper;
import com.roads.supervisor.mapper.SupMeterageDetailWinterMapper;
import com.roads.supervisor.mapper.SupPeriodMapper;
import com.roads.supervisor.mapper.SupSummaryBoqMapper;
import com.roads.supervisor.mapper.SupSummaryIpcMapper;
import com.roads.supervisor.mapper.SupSummaryRecordMapper;
import com.roads.supervisor.service.ISupSummaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SummaryServiceImpl
 * @Description 监理汇总service实现类
 * @Author nhp
 * @Date 2022/7/14 0014 18:03
 * @Version 1.0.0
 **/
@Service
public class SupSummaryServiceImpl implements ISupSummaryService {

    @Autowired
    private SupSummaryRecordMapper summaryRecordMapper;

    @Autowired
    private SupPeriodMapper periodMapper;

    @Autowired
    private SupBoqMapper boqMapper;

    @Autowired
    private SupSummaryBoqMapper summaryBoqMapper;

    @Autowired
    private SupSummaryIpcMapper summaryIpcMapper;

    @Autowired
    private SupMeterageDetailConstructionMapper detailConstructionMapper;

    @Autowired
    private SupMeterageDetailWinterMapper detailWinterMapper;

    @Autowired
    private SupMeterageDetailDefectMapper detailDefectMapper;

    @Autowired
    private SupMeterageDetailOtherMapper detailOtherMapper;

    @Autowired
    private ProInstitutionMapper institutionMapper;

    @Autowired
    private ProInstitutionDetailMapper institutionDetailMapper;

    @Autowired
    private ProSupervisorItemsMapper supervisorItemsMapper;

    /**
     * 获取汇总记录
     *
     * @param summaryRecord 汇总记录
     * @return 汇总记录
     */
    @Override
    public SupSummaryRecord getSummaryRecord(SupSummaryRecord summaryRecord) {
        return summaryRecordMapper.getSummaryRecord(summaryRecord.getCreateBy(), summaryRecord.getInstitutionCode(), summaryRecord.getPeriodName());
    }

    /**
     * 根据机构编号，工期获取汇总用户集合
     *
     * @param institutionCode 机构编号
     * @param periodName 工期
     * @return 汇总用户集合
     */
    @Override
    public List<SupSummaryRecordUserVo> selectSummaryRecordUserList(String institutionCode, String periodName) {
        return summaryRecordMapper.selectSummaryRecordUserList(institutionCode, periodName);
    }

    /**
     * 查询当前登录用户在监理计量流程节点出现的次数
     * @param user 当前登录用户
     * @return 数量
     */
    @Override
    public int getCountWorkflowNodeUser(String user) {
        return summaryRecordMapper.getCountWorkflowNodeUser(user);
    }

    /**
     * 获取汇总批复记录
     *
     * @param institutionCode 机构编号
     * @param periodName 工期
     * @return 汇总记录
     */
    @Override
    public SupSummaryRecord getSummaryRecordByApprove(String institutionCode, String periodName) {
        return summaryRecordMapper.getSummaryRecordIsApprove(institutionCode, periodName);
    }

    /**
     * 查看汇总是否批复
     *
     * @param institutionCode 机构编号
     * @param periodName 工期
     * @return 是否批复
     */
    @Override
    public boolean getSummaryIsApprove(String institutionCode, String periodName) {
        SupSummaryRecord summaryRecord = summaryRecordMapper.getSummaryRecordIsApprove(institutionCode, periodName);
        return StringUtils.isNotNull(summaryRecord);
    }

    /**
     * 数据汇总
     *
     * @param model 汇总实体对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int summary(SupSummaryVo model) {
        long startTime = System.currentTimeMillis();
        // 1.设置属性
        setAttribute(model);
        // 2.汇总记录
        summaryRecord(model);
        // 3.汇总清单
        List<SupSummaryBoq> summaryBoqList = new ArrayList<>();
        summaryBoq(model, summaryBoqList);
        // 4.汇总中期支付证书
        summaryIpc(model, summaryBoqList);
        long endTime = System.currentTimeMillis();
        System.out.println("汇总方法耗时：" + (endTime - startTime) + " ms");
        System.out.println(model.toString());
        return 1;
    }

    /**
     * 1.设置属性
     * ①设置上一期次
     * ②设置
     *
     * @param model 汇总实体对象
     */
    public void setAttribute(SupSummaryVo model) {
        long startTime = System.currentTimeMillis();
        SupPeriod currentPeriod = periodMapper.getPeriodByPeriodName(model.getInstitutionCode(), model.getPeriodName());
        model.setTemplateCode(currentPeriod.getTemplateCode());
        // 如果本期为第一期，设置上一期次为0
        if (Constants.FIRST_PERIOD.equals(model.getPeriodName())) {
            model.setLastPeriodName("0");
        } else {
            // 监理计量存在模板问题，上一期必须是和本期模板相同的一期
            SupPeriod lastPeriod = periodMapper.getUpperPeriodByTemplate(currentPeriod.getInstitutionCode(), currentPeriod.getTemplateCode(), currentPeriod.getPeriodId());
            // 如果同模板上一期为空，设置上一期为0
            if (StringUtils.isNull(lastPeriod)) {
                model.setLastPeriodName("0");
            } else {
                model.setLastPeriodName(lastPeriod.getPeriodName());
            }
        }
        // 设置上一期批复用户
        if (!"0".equals(model.getLastPeriodName())) {
            SupSummaryRecord summaryRecord = summaryRecordMapper.getSummaryRecordIsApprove(model.getInstitutionCode(), model.getLastPeriodName());
            if (StringUtils.isNotNull(summaryRecord)) {
                model.setApproveUser(summaryRecord.getCreateBy());
            } else {
                model.setApproveUser(model.getUserName());
            }
        }
        // 设置工期零填充
        if (Integer.parseInt(model.getPeriodName()) < 10) {
            model.setPeriodNameZeroFilling("0" + model.getPeriodName());
        }
        // 重置当前其次
        resetCurrentPeriod(model);
        long endTime = System.currentTimeMillis();
        System.out.println("重置标段编号耗时：" + (endTime - startTime) + " ms");
    }

    /**
     * 重置当前期次
     *
     * @param model 汇总实体对象
     */
    private void resetCurrentPeriod(SupSummaryVo model) {
        // 最终批复，需要将当前期次更改为下一期
        if (Constants.YES.equals(model.getIsApprove())) {
            // 设置下一期为当前计量期次
            String nextPeriodName = String.valueOf(Integer.parseInt(model.getPeriodName()) + 1);
            periodMapper.updateCurrentMeteragePeriod(model.getInstitutionCode(), nextPeriodName);
            // 设置除下一期以外期次为非当前计量期次
            periodMapper.updateNotCurrentMeteragePeriod(model.getInstitutionCode(), nextPeriodName);
            // 设置本期为锁定状态
            periodMapper.lockPeriod(model.getInstitutionCode(), model.getPeriodName());
        } else {
            // 判断是否为解锁操作
            SupSummaryRecord summaryRecord = summaryRecordMapper.getSummaryRecord(model.getUserName(), model.getInstitutionCode(), model.getPeriodName());
            // 查看以前是否汇总过，如果汇总过，并且是批复汇总，并且本次汇总为非汇总批复，视为解锁操作
            if (StringUtils.isNotNull(summaryRecord)
                    && Constants.YES.equals(summaryRecord.getIsApprove())
                    && Constants.NO.equals(model.getIsApprove())) {
                // 设置本期为当前计量期次
                periodMapper.updateCurrentMeteragePeriod(model.getInstitutionCode(), model.getPeriodName());
                // 设置除本期以外期次为非当前计量期次
                periodMapper.updateNotCurrentMeteragePeriod(model.getInstitutionCode(), model.getPeriodName());
                // 设置本期为非锁定状态
                periodMapper.unlockPeriod(model.getInstitutionCode(), model.getPeriodName());
            }
        }
    }

    /**
     * 2.汇总记录表
     *
     * @param model 汇总实体对象
     */
    private void summaryRecord(SupSummaryVo model) {
        long startTime = System.currentTimeMillis();
        SupSummaryRecord summaryRecord = summaryRecordMapper.getSummaryRecord(model.getUserName(), model.getInstitutionCode(), model.getPeriodName());
        if (StringUtils.isNotNull(summaryRecord)) {
            // 修改汇总记录
            summaryRecord.setInstitutionCode(model.getInstitutionCode());
            summaryRecord.setPeriodName(model.getPeriodName());
            summaryRecord.setIsApprove(model.getIsApprove());
            summaryRecord.setCreateBy(model.getUserName());
            summaryRecord.setCreateTime(model.getSummaryDate());
            summaryRecordMapper.update(summaryRecord);
        } else {
            summaryRecord = new SupSummaryRecord();
            summaryRecord.setInstitutionCode(model.getInstitutionCode());
            summaryRecord.setPeriodName(model.getPeriodName());
            summaryRecord.setIsApprove(model.getIsApprove());
            summaryRecord.setCreateBy(model.getUserName());
            summaryRecord.setCreateTime(model.getSummaryDate());
            summaryRecordMapper.insert(summaryRecord);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("汇总记录耗时：" + (endTime - startTime) + " ms");
    }

    /**
     * 3.汇总清单表
     *
     * @param model 汇总实体对象
     * @param summaryBoqList 汇总清单集合
     */
    private void summaryBoq(SupSummaryVo model, List<SupSummaryBoq> summaryBoqList){
        long startTime = System.currentTimeMillis();
        // 删除本期数据
        summaryBoqMapper.deleteSummaryBoq(model.getInstitutionCode(), model.getPeriodName(), model.getUserName());
        List<SupBoq> boqList = boqMapper.selectSummaryList(model.getInstitutionCode(), model.getTemplateCode());
        // 3.1 初始化汇总清单
        initSummaryBoq(summaryBoqList, boqList, model);
        // 3.2 更新施工，冬休，缺陷：合同单价，折旧费，数量，期数，金额。 更新本期施工，冬休，缺陷：数量，期数，金额
        updateSummaryBoq(summaryBoqList, model);
        // 3.3 汇总父项值
        updateSummaryBoqParent(summaryBoqList);
        // 3.4 更新本期合计值，上期末工期，金额
        updateSummaryBoqOther(summaryBoqList);
        // 批量插入数据库
        summaryBoqMapper.insertBatch(summaryBoqList);

        long endTime = System.currentTimeMillis();
        System.out.println("汇总清单耗时：" + (endTime - startTime) + " ms");
    }

    /**
     * 3.1 初始化汇总清单
     *
     * @param summaryBoqList 汇总清单集合
     * @param boqList 合同清单集合
     * @param model 汇总实体对象
     */
    private void initSummaryBoq(List<SupSummaryBoq> summaryBoqList, List<SupBoq> boqList, SupSummaryVo model) {
        int orderNum = 1;
        for (SupBoq boq : boqList) {
            SupSummaryBoq summaryBoq = new SupSummaryBoq();
            summaryBoq.setBdbh(model.getInstitutionCode());
            summaryBoq.setQc(model.getPeriodName());
            summaryBoq.setQdbh(boq.getBoqCode());
            summaryBoq.setQdmc(boq.getBoqName());
            summaryBoq.setPid(boq.getParentCode());
            summaryBoq.setZj(boq.getAncestors());
            summaryBoq.setSfyjd(boq.getLeafNode());
            summaryBoq.setDw(boq.getUnit());
            summaryBoq.setPx(BigDecimal.valueOf(orderNum++));
            summaryBoq.setCjz(model.getUserName());
            summaryBoq.setCjsj(model.getSummaryDate());
            summaryBoqList.add(summaryBoq);
        }
    }

    /**
     * 3.2 更新施工，冬休，缺陷：合同单价，折旧费，数量，期数，金额。 更新本期施工，冬休，缺陷：数量，期数，金额
     *
     * @param summaryBoqList 汇总清单集合
     * @param model 汇总实体对象
     */
    private void updateSummaryBoq(List<SupSummaryBoq> summaryBoqList, SupSummaryVo model) {
        SupBoq search = new SupBoq();
        search.setInstitutionCode(model.getInstitutionCode());
        search.setTemplateCode(model.getTemplateCode());
        // 施工期合同清单
        search.setBoqType(Constants.SUPERVISION_BOQ_TYPE_CONSTRUCTION);
        List<SupBoq> sgList = boqMapper.selectModelList(search);
        // 冬休期合同清单
        search.setBoqType(Constants.SUPERVISION_BOQ_TYPE_WINTER);
        List<SupBoq> dxList = boqMapper.selectModelList(search);
        // 缺陷期合同清单
        search.setBoqType(Constants.SUPERVISION_BOQ_TYPE_DEFECT);
        List<SupBoq> qxList = boqMapper.selectModelList(search);
        // 转成map
        Map<String, SupBoq> sgMap = new HashMap<>(sgList.size());
        for (SupBoq boq : sgList) {
            sgMap.put(boq.getBoqCode(), boq);
        }
        Map<String, SupBoq> dxMap = new HashMap<>(dxList.size());
        for (SupBoq boq : dxList) {
            dxMap.put(boq.getBoqCode(), boq);
        }
        Map<String, SupBoq> qxMap = new HashMap<>(qxList.size());
        for (SupBoq boq : qxList) {
            qxMap.put(boq.getBoqCode(), boq);
        }
        // 上期末相关数据
        SupSummaryBoq upperSearch = new SupSummaryBoq();
        upperSearch.setBdbh(model.getInstitutionCode());
        upperSearch.setQc(model.getLastPeriodName());
        upperSearch.setCjz(model.getApproveUser());
        List<SupSummaryBoq> upperList = summaryBoqMapper.selectModelList(upperSearch);
        // 本期相关数据
        List<SupMeterageDetailConstruction> bqSgList = detailConstructionMapper.selectCurrentPeriodList(model.getInstitutionCode(), model.getPeriodName(), model.getUserName());
        List<SupMeterageDetailWinter> bqDxList = detailWinterMapper.selectCurrentPeriodList(model.getInstitutionCode(), model.getPeriodName(), model.getUserName());
        List<SupMeterageDetailDefect> bqQxList = detailDefectMapper.selectCurrentPeriodList(model.getInstitutionCode(), model.getPeriodName(), model.getUserName());
        for (SupSummaryBoq summaryBoq : summaryBoqList) {
            // 取上期末
            if (StringUtils.isNotNull(upperList) && upperList.size() > 0) {
                for (SupSummaryBoq upperSummaryBoq : upperList) {
                    if (summaryBoq.getQdbh().equals(upperSummaryBoq.getQdbh()) && summaryBoq.getQdmc().equals(upperSummaryBoq.getQdmc())) {
                        summaryBoq.setSqmsgys(upperSummaryBoq.getBqmsgys());
                        summaryBoq.setSqmsgje(upperSummaryBoq.getBqmsgje());
                        summaryBoq.setSqmdxys(upperSummaryBoq.getBqmdxys());
                        summaryBoq.setSqmdxje(upperSummaryBoq.getBqmdxje());
                        summaryBoq.setSqmqxys(upperSummaryBoq.getBqmqxys());
                        summaryBoq.setSqmqxje(upperSummaryBoq.getBqmqxje());
                        summaryBoq.setSqmhjys(upperSummaryBoq.getBqmhjys());
                        summaryBoq.setSqmhjje(upperSummaryBoq.getBqmhjje());
                        break;
                    }
                }
            }
            // 施工合同
            SupBoq sgBoq = sgMap.get(summaryBoq.getQdbh());
            if (StringUtils.isNotNull(sgBoq)) {
                if (sgBoq.getBoqName().equals(summaryBoq.getQdmc())) {
                    summaryBoq.setHtsgdj(sgBoq.getPrice());
                    summaryBoq.setHtsgzjf(sgBoq.getDepreciationTotal());
                    summaryBoq.setHtsgrs(sgBoq.getPersonAmount());
                    summaryBoq.setHtsgys(sgBoq.getPeriodAmount());
                    summaryBoq.setHtsgje(sgBoq.getTotal());
                }
            }
            // 冬休合同
            SupBoq dxBoq = dxMap.get(summaryBoq.getQdbh());
            if (StringUtils.isNotNull(dxBoq)) {
                if (dxBoq.getBoqName().equals(summaryBoq.getQdmc())) {
                    summaryBoq.setHtdxdj(dxBoq.getPrice());
                    summaryBoq.setHtdxzjf(dxBoq.getDepreciationTotal());
                    summaryBoq.setHtdxrs(dxBoq.getPersonAmount());
                    summaryBoq.setHtdxys(dxBoq.getPeriodAmount());
                    summaryBoq.setHtdxje(dxBoq.getTotal());
                }
            }
            // 缺陷合同
            SupBoq qxBoq = qxMap.get(summaryBoq.getQdbh());
            if (StringUtils.isNotNull(qxBoq)) {
                if (qxBoq.getBoqName().equals(summaryBoq.getQdmc())) {
                    summaryBoq.setHtqxdj(qxBoq.getPrice());
                    summaryBoq.setHtqxzjf(qxBoq.getDepreciationTotal());
                    summaryBoq.setHtqxrs(qxBoq.getPersonAmount());
                    summaryBoq.setHtqxys(qxBoq.getPeriodAmount());
                    summaryBoq.setHtqxje(qxBoq.getTotal());
                }
            }
            // 施工本期
            if (StringUtils.isNotNull(bqSgList) && bqSgList.size() > 0) {
                for (SupMeterageDetailConstruction detail : bqSgList) {
                    if (summaryBoq.getQdbh().equals(detail.getBoqCode()) && summaryBoq.getQdmc().equals(detail.getBoqName())) {
                        summaryBoq.setBqsgys(detail.getPeriodAmount());
                        summaryBoq.setBqsgrs(detail.getPersonAmount());
                        summaryBoq.setBqsgje(detail.getTotal());
                        break;
                    }
                }
            }
            // 冬休本期
            if (StringUtils.isNotNull(bqDxList) && bqDxList.size() > 0) {
                for (SupMeterageDetailWinter detail : bqDxList) {
                    if (summaryBoq.getQdbh().equals(detail.getBoqCode()) && summaryBoq.getQdmc().equals(detail.getBoqName())) {
                        summaryBoq.setBqdxys(detail.getPeriodAmount());
                        summaryBoq.setBqdxrs(detail.getPersonAmount());
                        summaryBoq.setBqdxje(detail.getTotal());
                        break;
                    }
                }
            }
            // 缺陷本期
            if (StringUtils.isNotNull(bqQxList) && bqQxList.size() > 0) {
                for (SupMeterageDetailDefect detail : bqQxList) {
                    if (summaryBoq.getQdbh().equals(detail.getBoqCode()) && summaryBoq.getQdmc().equals(detail.getBoqName())) {
                        summaryBoq.setBqqxys(detail.getPeriodAmount());
                        summaryBoq.setBqqxrs(detail.getPersonAmount());
                        summaryBoq.setBqqxje(detail.getTotal());
                        break;
                    }
                }
            }
        }
    }

    /**
     * 3.3 更新父项值
     *
     * @param summaryBoqList 汇总清单集合
     */
    private void updateSummaryBoqParent(List<SupSummaryBoq> summaryBoqList) {
        for (SupSummaryBoq summaryBoq : summaryBoqList) {
            if (Constants.NO.equals(summaryBoq.getSfyjd())) {
                BigDecimal pHtsgje = BigDecimal.valueOf(0);
                BigDecimal pHtdxje = BigDecimal.valueOf(0);
                BigDecimal pHtqxje = BigDecimal.valueOf(0);
                BigDecimal pBqsgje = BigDecimal.valueOf(0);
                BigDecimal pBqdxje = BigDecimal.valueOf(0);
                BigDecimal pBqqxje = BigDecimal.valueOf(0);
                for (int i = 0; i < summaryBoqList.size(); i++) {
                    SupSummaryBoq children = summaryBoqList.get(i);
                    if (Constants.YES.equals(children.getSfyjd()) && children.getZj().contains(summaryBoq.getQdbh())) {
                        BigDecimal htsgje = children.getHtsgje() == null ? BigDecimal.valueOf(0) : children.getHtsgje();
                        pHtsgje = pHtsgje.add(htsgje);
                        BigDecimal htdxje = children.getHtdxje() == null ? BigDecimal.valueOf(0) : children.getHtdxje();
                        pHtdxje = pHtdxje.add(htdxje);
                        BigDecimal htqxje = children.getHtqxje() == null ? BigDecimal.valueOf(0) : children.getHtqxje();
                        pHtqxje = pHtqxje.add(htqxje);
                        BigDecimal bqsgje = children.getBqsgje() == null ? BigDecimal.valueOf(0) : children.getBqsgje();
                        pBqsgje = pBqsgje.add(bqsgje);
                        BigDecimal bqdxje = children.getBqdxje() == null ? BigDecimal.valueOf(0) : children.getBqdxje();
                        pBqdxje = pBqdxje.add(bqdxje);
                        BigDecimal bqqxje = children.getBqqxje() == null ? BigDecimal.valueOf(0) : children.getBqqxje();
                        pBqqxje = pBqqxje.add(bqqxje);
                    }
                }
                summaryBoq.setHtsgje(pHtsgje);
                summaryBoq.setHtdxje(pHtdxje);
                summaryBoq.setHtqxje(pHtqxje);
                summaryBoq.setBqsgje(pBqsgje);
                summaryBoq.setBqdxje(pBqdxje);
                summaryBoq.setBqqxje(pBqqxje);
            }
        }
    }

    /**
     * 3.4 更新合同合计，本期合计值，上期末工期，金额
     *
     * @param summaryBoqList 汇总清单集合
     */
    private void updateSummaryBoqOther(List<SupSummaryBoq> summaryBoqList) {
        for (SupSummaryBoq summaryBoq : summaryBoqList) {
            // 合同合计
            BigDecimal htsgje = summaryBoq.getHtsgje() == null ? BigDecimal.valueOf(0) : summaryBoq.getHtsgje();
            BigDecimal htdxje = summaryBoq.getHtdxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getHtdxje();
            BigDecimal htqxje = summaryBoq.getHtqxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getHtqxje();
            BigDecimal hthj = htsgje.add(htdxje).add(htqxje);
            summaryBoq.setHthj(hthj);
            // 更新本期合计金额
            BigDecimal bqsgje = summaryBoq.getBqsgje() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqsgje();
            BigDecimal bqdxje = summaryBoq.getBqdxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqdxje();
            BigDecimal bqqxje = summaryBoq.getBqqxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqqxje();
            BigDecimal bqhjje = bqsgje.add(bqdxje).add(bqqxje);
            summaryBoq.setBqhjje(bqhjje);
            // 本期末数据
            BigDecimal sqmsgys = summaryBoq.getSqmsgys() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmsgys();
            BigDecimal bqsgys = summaryBoq.getBqsgys() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqsgys();
            BigDecimal bqmsgys = sqmsgys.add(bqsgys);
            summaryBoq.setBqmsgys(bqmsgys);
            BigDecimal sqmdxys = summaryBoq.getSqmdxys() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmdxys();
            BigDecimal bqdxys = summaryBoq.getBqdxys() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqdxys();
            BigDecimal bqmdxys = sqmdxys.add(bqdxys);
            summaryBoq.setBqmdxys(bqmdxys);
            BigDecimal sqmqxys = summaryBoq.getSqmqxys() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmqxys();
            BigDecimal bqqxys = summaryBoq.getBqqxys() == null ? BigDecimal.valueOf(0) : summaryBoq.getBqqxys();
            BigDecimal bqmqxys = sqmqxys.add(bqqxys);
            summaryBoq.setBqmqxys(bqmqxys);

            BigDecimal sqmsgje = summaryBoq.getSqmsgje() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmsgje();
            BigDecimal bqmsgje = sqmsgje.add(bqsgje);
            summaryBoq.setBqmsgje(bqmsgje);
            BigDecimal sqmdxje = summaryBoq.getSqmdxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmdxje();
            BigDecimal bqmdxje = sqmdxje.add(bqdxje);
            summaryBoq.setBqmdxje(bqmdxje);
            BigDecimal sqmqxje = summaryBoq.getSqmqxje() == null ? BigDecimal.valueOf(0) : summaryBoq.getSqmqxje();
            BigDecimal bqmqxje = sqmqxje.add(bqqxje);
            summaryBoq.setBqmqxje(bqmqxje);
            BigDecimal bqmhjje = bqmsgje.add(bqmdxje).add(bqmqxje);
            summaryBoq.setBqmhjje(bqmhjje);

        }
    }

    /**
     * 4. 汇总中期支付表
     * @param model 汇总实体对象
     * @param summaryBoqList 汇总清单集合
     */
    private void summaryIpc(SupSummaryVo model, List<SupSummaryBoq> summaryBoqList) {
        long startTime = System.currentTimeMillis();
        // 删除数据
        summaryIpcMapper.deleteSummaryIpc(model.getInstitutionCode(), model.getPeriodName(), model.getUserName());
        // 获取标段
        ProInstitution institution = institutionMapper.getModelByInnerCode(model.getInstitutionCode());
        ProInstitutionDetail institutionDetail = institutionDetailMapper.getModelByInnerCode(model.getInstitutionCode());
        // 获取项目支付项目
        ProSupervisorItems search = new ProSupervisorItems();
        search.setProjectId(institution.getProjectId());
        search.setItemStatus(Constants.SUCCESS);
        List<ProSupervisorItems> paymentItems = supervisorItemsMapper.selectModelList(search);
        List<SupSummaryIpc> ipcList = new ArrayList<>();
        // 4.1 初始化中期支付证书
        initSummaryIpc(model, paymentItems, ipcList);
        // 4.2 更新施工期、冬休期、缺陷期合同金额，上期末，本期，本期末金额
        updateSummaryTotal(ipcList, summaryBoqList);
        // 4.2.1 更新某些支付项目合同金额
        updateSummaryContractTotal(institutionDetail, ipcList);
        // 4.3 更新其他支付项目的上期末，本期，本期末金额
        updateSummaryOther(institutionDetail, model, ipcList);
        // 4.4 更新本期完成百分比和本期末完成百分比
        updateSummaryIpcRatio(ipcList);
        // 批量插入
        summaryIpcMapper.insertBatch(ipcList);
        long endTime = System.currentTimeMillis();
        System.out.println("汇总中期支付证书耗时：" + (endTime - startTime) + " ms");
    }

    /**
     * 4.1 初始化中期支付证书
     *
     * @param model 汇总实体对象
     * @param paymentItems 支付项目
     * @param ipcList 中期支付证书集合
     */
    private void initSummaryIpc(SupSummaryVo model, List<ProSupervisorItems> paymentItems, List<SupSummaryIpc> ipcList) {
        // 初始化中期支付证书 支付项目
        for (ProSupervisorItems paymentItem : paymentItems) {
            SupSummaryIpc ipc = new SupSummaryIpc();
            ipc.setBdbh(model.getInstitutionCode());
            ipc.setQc(model.getPeriodName());
            ipc.setXmbh(paymentItem.getItemCode());
            ipc.setXmmc(paymentItem.getItemName());
            ipc.setPx(paymentItem.getItemOrder());
            ipc.setFh(paymentItem.getSign());
            ipc.setJsfs(paymentItem.getComputeMode());
            ipc.setBzxm(paymentItem.getHundredItem());
            ipc.setHjxm(paymentItem.getSumItem());
            ipc.setBfbxm(paymentItem.getPercentageItem());
            ipc.setBfb(paymentItem.getRatio());
            ipc.setCjz(model.getUserName());
            ipc.setCjsj(model.getSummaryDate());
            ipcList.add(ipc);
        }
    }

    /**
     * 4.1.1 更新某些支付项目的合同金额
     *
     * @param institutionDetail 标段详情
     * @param ipcList 中期支付证书集合
     */
    private void updateSummaryContractTotal(ProInstitutionDetail institutionDetail, List<SupSummaryIpc> ipcList) {
        for (SupSummaryIpc ipc: ipcList) {
            if (PaymentConstant.ZQZFZS_LR.equalsIgnoreCase(ipc.getXmbh())) {
                ipc.setHthjje(institutionDetail.getProfitTotal());
            } else if (PaymentConstant.ZQZFZS_ZDJ.equalsIgnoreCase(ipc.getXmbh())) {
                ipc.setHthjje(institutionDetail.getProvisionalDepositTotal());
            } else if (PaymentConstant.ZQZFZS_DLF.equalsIgnoreCase(ipc.getXmbh())) {
                // 代理费合同金额
                ipc.setHthjje(institutionDetail.getAgentTotal());
            } else if (PaymentConstant.ZQZFZS_QXZRQFY.equalsIgnoreCase(ipc.getXmbh())) {
                // 缺陷责任期合同金额
                BigDecimal qxzrq = BigDecimal.ZERO;
                for (SupSummaryIpc qd : ipcList) {
                    if (qd.getJsfs() == 1) {
                        BigDecimal total = qd.getHtqxje() == null ? BigDecimal.ZERO : qd.getHtqxje();
                        qxzrq = qxzrq.add(total);
                    }
                }
                ipc.setHtsgje(qxzrq);
            }
        }
    }

    /**
     * 4.2 更新施工期、冬休期、缺陷期合同金额，上期末，本期，本期末金额
     *
     * @param ipcList 中期支付证书集合
     * @param summaryBoqList 汇总清单集合
     */
    private void updateSummaryTotal(List<SupSummaryIpc> ipcList, List<SupSummaryBoq> summaryBoqList) {
        for (SupSummaryIpc ipc: ipcList) {
            if (ipc.getJsfs() == 1) {
                for (int i = 0; i < summaryBoqList.size(); i++) {
                    SupSummaryBoq summaryBoq = summaryBoqList.get(i);
                    if (StringUtils.isNotNull(summaryBoq)) {
                        if (ipc.getXmbh().equals(summaryBoq.getQdbh())) {
                            ipc.setHtsgje(summaryBoq.getHtsgje());
                            ipc.setHtdxje(summaryBoq.getHtdxje());
                            ipc.setHtqxje(summaryBoq.getHtqxje());
                            ipc.setHthjje(summaryBoq.getHthj());
                            ipc.setSqmsgje(summaryBoq.getSqmsgje());
                            ipc.setSqmdxje(summaryBoq.getSqmdxje());
                            ipc.setSqmqxje(summaryBoq.getSqmqxje());
                            ipc.setSqmhjje(summaryBoq.getSqmhjje());
                            ipc.setBqsgje(summaryBoq.getBqsgje());
                            ipc.setBqdxje(summaryBoq.getBqdxje());
                            ipc.setBqqxje(summaryBoq.getBqqxje());
                            ipc.setBqhjje(summaryBoq.getBqhjje());
                            ipc.setBqmsgje(summaryBoq.getBqmsgje());
                            ipc.setBqmdxje(summaryBoq.getBqmdxje());
                            ipc.setBqmqxje(summaryBoq.getBqmqxje());
                            ipc.setBqmhjje(summaryBoq.getBqmhjje());
                            break;
                        }
                    }
                }
            }
        }
    }

    /**
     * 4.3 更新其他支付项目的上期末，本期，本期末金额
     *
     * @param institutionDetail 标段详情
     * @param model 汇总实体对象
     * @param ipcList 中期支付证书集合
     */
    private void updateSummaryOther(ProInstitutionDetail institutionDetail, SupSummaryVo model, List<SupSummaryIpc> ipcList) {
        // 取出上期数据
        SupSummaryIpc lastSearch = new SupSummaryIpc();
        lastSearch.setBdbh(model.getInstitutionCode());
        lastSearch.setQc(model.getLastPeriodName());
        lastSearch.setCjz(model.getApproveUser());
        List<SupSummaryIpc> lastIpcList = summaryIpcMapper.selectModelList(lastSearch);
        Map<String, SupSummaryIpc> lastIpcMap = new HashMap<>(lastIpcList.size());
        Map<String, SupSummaryIpc> ipcMap = new HashMap<>(lastIpcList.size());
        // 转map
        for (SupSummaryIpc ipc : lastIpcList) {
            lastIpcMap.put(ipc.getXmbh(), ipc);
        }
        // 获取固定值数据
        SupMeterageDetailOther searchOther = new SupMeterageDetailOther();
        searchOther.setItemName(model.getInstitutionCode());
        searchOther.setItemCode(model.getPeriodName());
        searchOther.setUser(model.getUserName());
        List<SupMeterageDetailOther> otherList = detailOtherMapper.selectModelListBySummary(searchOther);
        // 循环处理
        for (SupSummaryIpc ipc : ipcList) {
            // 上期末金额
            if (ipc.getJsfs() != 1) {
                if (!"0".equals(model.getLastPeriodName())) {
                    SupSummaryIpc lastIpc = lastIpcMap.get(ipc.getXmbh());
                    if (StringUtils.isNotNull(lastIpc)) {
                        ipc.setSqmhjje(lastIpc.getBqmhjje());
                        ipc.setSqmsgje(lastIpc.getBqmsgje());
                        ipc.setSqmdxje(lastIpc.getBqmdxje());
                        ipc.setSqmqxje(lastIpc.getBqmqxje());
                    }
                } else {
                    ipc.setSqmhjje(BigDecimal.valueOf(0));
                    ipc.setSqmsgje(BigDecimal.valueOf(0));
                    ipc.setSqmdxje(BigDecimal.valueOf(0));
                    ipc.setSqmqxje(BigDecimal.valueOf(0));
                }
            }
            // 本期金额、本期末金额
            if (ipc.getJsfs() == 4) {
                // 本期金额、本期末金额--固定值
                updateSummaryIpcFixedValue(ipc, otherList);
            } else if (ipc.getJsfs() == 5){
                updateSummaryIpcOther(institutionDetail, ipc, ipcMap);
            } else if (ipc.getJsfs() == 3) {
                // 本期金额、本期末金额--百分比
                updateSummaryIpcPercentage(ipc, ipcMap);
            } else if (ipc.getJsfs() == 2 ) {
                // 本期金额、本期末金额--合计
                updateSummaryIpcSum(ipc, ipcMap);
            }
            if (PaymentConstant.ZQZFZS_QXZRQFY.equalsIgnoreCase(ipc.getXmbh())) {
                // 本期金额、本期末金额、上期末金额--缺陷责任期
                updateSummaryIpcDefect(ipc, ipcMap);
            }
            ipcMap.put(ipc.getXmbh(), ipc);
        }
    }

    /**
     * 中期支付证书固定值更新
     *
     * @param ipc 中期支付证书支付项目
     * @param otherList 固定值集合
     */
    private void updateSummaryIpcFixedValue(SupSummaryIpc ipc, List<SupMeterageDetailOther> otherList) {
        for (SupMeterageDetailOther other : otherList) {
            if (other.getItemCode().equals(ipc.getXmbh())) {
                BigDecimal fixedValue = other.getTotal() == null ? BigDecimal.valueOf(0) : other.getTotal();
                BigDecimal lastPeriodTotal = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
                ipc.setBqhjje(fixedValue);
                ipc.setBqmhjje(lastPeriodTotal.add(fixedValue));
            }
        }
    }

    /**
     * 中期支付证书其他值更新
     *
     * @param institutionDetail 标段详情
     * @param ipc 中期支付证书支付项目
     * @param ipcMap 中期支付证书支付项目map集合
     */
    private void updateSummaryIpcOther(ProInstitutionDetail institutionDetail, SupSummaryIpc ipc, Map<String, SupSummaryIpc> ipcMap) {
        if (PaymentConstant.ZQZFZS_KHBLJ.equals(ipc.getXmbh())) {
            updateSummaryIpcKhblj(institutionDetail, ipc, ipcMap);
        } else if (PaymentConstant.ZQZFZS_KHDYYFK.equals(ipc.getXmbh())) {
            updateSummaryIpcMobilizationAdvancePayment(ipc, institutionDetail, ipcMap);
        } else if (PaymentConstant.ZQZFZS_LR.equalsIgnoreCase(ipc.getXmbh())) {
            updateSummaryIpcLrTotal(ipc, institutionDetail, ipcMap);
        }
    }

    /**
     * 中期支付证书-扣回保留金
     *
     * @param institutionDetail 标段详情
     * @param ipc 中期支付证书支付项目 -- 扣回保留金
     * @param ipcMap 中期支付证书支付项目map集合
     */
    private void updateSummaryIpcKhblj(ProInstitutionDetail institutionDetail, SupSummaryIpc ipc, Map<String, SupSummaryIpc> ipcMap) {
        // 合同总价
        BigDecimal contractTotal = institutionDetail.getContractTotal() == null ? BigDecimal.valueOf(0) : institutionDetail.getContractTotal();
        // 本期末清单小计
        BigDecimal bqmqdxj = ipcMap.get(PaymentConstant.ZQZFZS_XJ).getBqmhjje() == null ? BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_XJ).getBqmhjje();
        int khbljxebl = institutionDetail.getRetentionMoneyQuota() == null ? 0 : institutionDetail.getRetentionMoneyQuota();
        // 扣回保留金限额
        BigDecimal khbljxe = contractTotal.multiply(BigDecimal.valueOf(khbljxebl)).divide(BigDecimal.valueOf(100), BigDecimal.ROUND_HALF_UP);
        // 本期末扣回保留金
        int khbljbl = institutionDetail.getRetentionMoneyDeduction() == null ? 0 : institutionDetail.getRetentionMoneyDeduction();
        BigDecimal bqmkhblje = bqmqdxj.multiply(BigDecimal.valueOf(khbljbl)).
                divide(BigDecimal.valueOf(100), institutionDetail.getDecimalPlace2(), BigDecimal.ROUND_HALF_UP).setScale(institutionDetail.getDecimalPlace2(), BigDecimal.ROUND_HALF_UP);
        // 如果本期末扣回扣回保留金额超过扣回保留金限额金额，则让本期末扣回保留金等于扣回保留金限额
        if (bqmkhblje.compareTo(khbljxe) > 0) {
            bqmkhblje = khbljxe;
        }
        // 上期末
        BigDecimal lastPeriodTotal = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
        BigDecimal currentPeriodTotal = bqmkhblje.subtract(lastPeriodTotal);
        ipc.setBqhjje(currentPeriodTotal);
        ipc.setBqmhjje(bqmkhblje);
    }

    /**
     * 扣回动员预付款 超过动员预付款起扣金额的部分，每完成合同总价的1%，扣除动员预付款的2%
     *
     * @param ipc 扣回动员预付款支付项目
     * @param institutionDetail 标段详情
     * @param ipcMap 支付项目map集合
     */
    private void updateSummaryIpcMobilizationAdvancePayment(SupSummaryIpc ipc, ProInstitutionDetail institutionDetail, Map<String, SupSummaryIpc> ipcMap) {
        // 合同金额
        BigDecimal contractTotal = institutionDetail.getContractTotal() == null ? BigDecimal.valueOf(0) : institutionDetail.getContractTotal();
        System.out.println("合同金额：" + contractTotal);
        // 动员预付款起扣比例
        int advancePaymentBegin = institutionDetail.getAdvancePaymentBegin() == null ? 0 : institutionDetail.getAdvancePaymentBegin();
        System.out.println("起扣比例：" + advancePaymentBegin);
        // 动员预付款起扣金额
        BigDecimal advancePaymentStartTotal = contractTotal.multiply(BigDecimal.valueOf(advancePaymentBegin)).divide(BigDecimal.valueOf(100), BigDecimal.ROUND_HALF_UP);
        System.out.println("起扣金额：" + advancePaymentStartTotal);
        // 本期末清单小计
        BigDecimal currentEndPeriodBoqSumTotal = ipcMap.get(PaymentConstant.ZQZFZS_HJ).getBqmhjje() == null ? BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_HJ).getBqmhjje();
        BigDecimal bqmqxje = ipcMap.get(PaymentConstant.ZQZFZS_QXZRQFY).getBqmhjje() == null ? BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_QXZRQFY).getBqmhjje();
        currentEndPeriodBoqSumTotal = currentEndPeriodBoqSumTotal.subtract(bqmqxje);
        System.out.println("本期末清单小计：" + currentEndPeriodBoqSumTotal);
        // 本期末清单小计大于动员付款起扣金额
        if (currentEndPeriodBoqSumTotal.compareTo(advancePaymentStartTotal) > 0) {
            // 动员预付款
            BigDecimal advancePaymentTotal = ipcMap.get(PaymentConstant.ZQZFZS_DYYFK).getBqmhjje() == null ?
                    BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_DYYFK).getBqmhjje();
            System.out.println("动员预付款：" + advancePaymentTotal);
            // 扣款金额
            BigDecimal deductionTotal = currentEndPeriodBoqSumTotal.subtract(advancePaymentStartTotal);
            BigDecimal mapCepTotal = deductionTotal.divide(contractTotal, 6, BigDecimal.ROUND_HALF_UP).
                    multiply(BigDecimal.valueOf(2)).
                    multiply(advancePaymentTotal).
                    setScale(institutionDetail.getDecimalPlace2(), BigDecimal.ROUND_HALF_UP);
            // 如果本期末扣回动员预付款超过本期末动员预付款，则让本期末扣回动员预付款等于本期末动员预付款
            if (mapCepTotal.compareTo(advancePaymentTotal) > 0) {
                mapCepTotal = advancePaymentTotal;
            }
            BigDecimal lastPeriodTotal = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
            BigDecimal currentPeriodTotal = mapCepTotal.subtract(lastPeriodTotal);
            ipc.setBqhjje(currentPeriodTotal);
            ipc.setBqmhjje(mapCepTotal);
        }
    }

    /**
     * 利润 利润本期计量金额=本期百章小计×（利润合同金额/清单合同金额）
     *
     * @param ipc 扣回动员预付款支付项目
     * @param institutionDetail 标段详情
     * @param ipcMap 支付项目map集合
     */
    public void updateSummaryIpcLrTotal(SupSummaryIpc ipc, ProInstitutionDetail institutionDetail, Map<String, SupSummaryIpc> ipcMap) {
        BigDecimal qdxjhtje = ipcMap.get(PaymentConstant.ZQZFZS_XJ).getHthjje() == null ?
                BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_XJ).getHthjje();
        BigDecimal bqsgje = ipcMap.get(PaymentConstant.ZQZFZS_XJ).getBqsgje() == null ?
                BigDecimal.valueOf(0) : ipcMap.get(PaymentConstant.ZQZFZS_XJ).getBqsgje();
        BigDecimal lrhtje = ipc.getHthjje() == null ? BigDecimal.valueOf(0) : ipc.getHthjje();
        BigDecimal bqlrje = BigDecimal.ZERO;
        if (qdxjhtje.compareTo(BigDecimal.ZERO) != 0) {
            BigDecimal value = lrhtje.divide(qdxjhtje, 6, BigDecimal.ROUND_HALF_UP);
            bqlrje = bqsgje.multiply(value).setScale(institutionDetail.getDecimalPlace2(), BigDecimal.ROUND_HALF_UP);
        }
        BigDecimal lrsqmje = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
        BigDecimal bqmhjje = lrsqmje.add(bqlrje);
        ipc.setBqhjje(bqlrje);
        ipc.setBqmhjje(bqmhjje);
    }

    /**
     * 中期支付证书-缺陷责任期
     *
     * @param ipc 中期支付证书支付项目 -- 缺陷责任期
     * @param ipcMap 中期支付证书支付项目map集合
     */
    private void updateSummaryIpcDefect(SupSummaryIpc ipc, Map<String, SupSummaryIpc> ipcMap) {
        // 取出缺陷责任期的计量数据
        SupSummaryIpc xjIpc = ipcMap.get(PaymentConstant.ZQZFZS_XJ);
        ipc.setBqsgje(xjIpc.getBqqxje());
        ipc.setSqmsgje(xjIpc.getSqmqxje());
        ipc.setBqmsgje(xjIpc.getBqmqxje());
    }

    /**
     * 4.4 中期支付证书比例值更新
     *
     * @param ipc 中期支付证书支付项目
     * @param ipcMap 中期支付证书支付项目map集合
     */
    private void updateSummaryIpcPercentage(SupSummaryIpc ipc, Map<String, SupSummaryIpc> ipcMap) {
        // 百分比项目， 百分比
        String percentageItem = ipc.getBfbxm();
        BigDecimal ratio = ipc.getBfb() == null ? BigDecimal.valueOf(0) : ipc.getBfb();
        if (StringUtils.isNotEmpty(percentageItem) && ratio.compareTo(BigDecimal.valueOf(0)) > 0) {
            SupSummaryIpc percentageIpc = ipcMap.get(percentageItem);
            if (StringUtils.isNotNull(percentageIpc)) {
                BigDecimal percentageTotal = percentageIpc.getBqhjje() == null ? BigDecimal.valueOf(0) : percentageIpc.getBqhjje();
                BigDecimal currentPeriodTotal = percentageTotal.multiply(ratio).divide(BigDecimal.valueOf(100), 12, BigDecimal.ROUND_HALF_UP).setScale(0, BigDecimal.ROUND_HALF_UP);
                BigDecimal lastPeriodTotal = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
                BigDecimal currentEndPeriodTotal = lastPeriodTotal.add(currentPeriodTotal);
                ipc.setBqhjje(currentPeriodTotal);
                ipc.setBqmhjje(currentEndPeriodTotal);
            }
        }
    }

    /**
     * 中期支付证书合计值更新
     *
     * @param ipc 中期支付证书支付项目
     * @param ipcMap 中期支付证书支付项目map集合
     */
    private void updateSummaryIpcSum(SupSummaryIpc ipc, Map<String, SupSummaryIpc> ipcMap) {
        String sumItem = ipc.getHjxm();
        if (StringUtils.isNotEmpty(sumItem)) {
            BigDecimal currentPeriodTotal = BigDecimal.valueOf(0);
            BigDecimal currentPeriodSumTotal = BigDecimal.valueOf(0);
            BigDecimal currentPeriodSgTotal = BigDecimal.ZERO;
            BigDecimal currentPeriodSgSumTotal = BigDecimal.ZERO;
            BigDecimal currentPeriodQxTotal = BigDecimal.ZERO;
            BigDecimal currentPeriodQxSumTotal = BigDecimal.ZERO;
            BigDecimal currentPeriodDxTotal = BigDecimal.ZERO;
            BigDecimal currentPeriodDxSumTotal = BigDecimal.ZERO;
            String[] itemArray = sumItem.split(",");
            for (String item: itemArray) {
                SupSummaryIpc itemIpc = ipcMap.get(item);
                if (StringUtils.isNotNull(itemIpc)) {
                    // 本期金额
                    BigDecimal itemCurrentPeriodTotal = itemIpc.getBqhjje() == null ? BigDecimal.valueOf(0) : itemIpc.getBqhjje();
                    BigDecimal sgPeriodTotal = itemIpc.getBqsgje() == null ? BigDecimal.ZERO : itemIpc.getBqsgje();
                    BigDecimal dxPeriodTotal = itemIpc.getBqdxje() == null ? BigDecimal.ZERO : itemIpc.getBqdxje();
                    BigDecimal qxPeriodTotal = itemIpc.getBqqxje() == null ? BigDecimal.ZERO : itemIpc.getBqqxje();
                    currentPeriodTotal = currentPeriodTotal.add(itemCurrentPeriodTotal.multiply(itemIpc.getFh()));
                    currentPeriodSgTotal = currentPeriodSgTotal.add(sgPeriodTotal.multiply(itemIpc.getFh()));
                    currentPeriodDxTotal = currentPeriodDxTotal.add(dxPeriodTotal.multiply(itemIpc.getFh()));
                    currentPeriodQxTotal = currentPeriodQxTotal.add(qxPeriodTotal.multiply(itemIpc.getFh()));
                    // 合同金额
                    BigDecimal hthjje = itemIpc.getHthjje() == null ? BigDecimal.valueOf(0) : itemIpc.getHthjje();
                    BigDecimal htsgje = itemIpc.getHtsgje() == null ? BigDecimal.ZERO : itemIpc.getHtsgje();
                    BigDecimal htdxje = itemIpc.getHtdxje() == null ? BigDecimal.ZERO : itemIpc.getHtdxje();
                    BigDecimal htqxje = itemIpc.getHtqxje() == null ? BigDecimal.ZERO : itemIpc.getHtqxje();
                    currentPeriodSumTotal = currentPeriodSumTotal.add(hthjje.multiply(itemIpc.getFh()));
                    currentPeriodSgSumTotal = currentPeriodSgSumTotal.add(htsgje.multiply(itemIpc.getFh()));
                    currentPeriodQxSumTotal = currentPeriodQxSumTotal.add(htqxje.multiply(itemIpc.getFh()));
                    currentPeriodDxSumTotal = currentPeriodDxSumTotal.add(htdxje.multiply(itemIpc.getFh()));
                }
            }
            ipc.setHthjje(currentPeriodSumTotal);
            ipc.setHtsgje(currentPeriodSgSumTotal);
            ipc.setHtqxje(currentPeriodQxSumTotal);
            ipc.setHtdxje(currentPeriodDxSumTotal);
            ipc.setBqhjje(currentPeriodTotal);
            ipc.setBqsgje(currentPeriodSgTotal);
            ipc.setBqqxje(currentPeriodQxTotal);
            ipc.setBqdxje(currentPeriodDxTotal);
            BigDecimal lastPeriodTotal = ipc.getSqmhjje() == null ? BigDecimal.valueOf(0) : ipc.getSqmhjje();
            BigDecimal currentEndPeriodTotal = lastPeriodTotal.add(currentPeriodTotal);
            ipc.setBqmhjje(currentEndPeriodTotal);
            BigDecimal lastPeriodSgTotal = ipc.getSqmsgje() == null ? BigDecimal.valueOf(0) : ipc.getSqmsgje();
            BigDecimal currentEndPeriodSgTotal = lastPeriodSgTotal.add(currentPeriodSgTotal);
            ipc.setBqmsgje(currentEndPeriodSgTotal);
            BigDecimal lastPeriodQxTotal = ipc.getSqmqxje() == null ? BigDecimal.valueOf(0) : ipc.getSqmqxje();
            BigDecimal currentEndPeriodQxTotal = lastPeriodQxTotal.add(currentPeriodQxTotal);
            ipc.setBqmqxje(currentEndPeriodQxTotal);
            BigDecimal lastPeriodDxTotal = ipc.getSqmdxje() == null ? BigDecimal.valueOf(0) : ipc.getSqmdxje();
            BigDecimal currentEndPeriodDxTotal = lastPeriodDxTotal.add(currentPeriodDxTotal);
            ipc.setBqmdxje(currentEndPeriodDxTotal);

        }
    }

    /**
     * 4.4 更新本期完成百分比和本期末完成百分比
     *
     * @param ipcList 中期支付证书 支付项目集合
     */
    private void updateSummaryIpcRatio(List<SupSummaryIpc> ipcList) {
        for (SupSummaryIpc ipc : ipcList) {
            Integer finishRatio = calRatio(ipc.getBqhjje(), ipc.getHthjje());
            ipc.setBqwcbl(finishRatio);
            Integer currentFinishRatio = calRatio(ipc.getBqmhjje(), ipc.getHthjje());
            ipc.setBqmwcbl(currentFinishRatio);
        }
    }

    /**
     * 计算比例
     *
     * @param val1 值1
     * @param val2 值2
     * @return 比例
     */
    private Integer calRatio(BigDecimal val1, BigDecimal val2) {
        if (StringUtils.isNotNull(val2) && val2.compareTo(BigDecimal.valueOf(0)) != 0) {
            if (StringUtils.isNotNull(val1) && val1.compareTo(BigDecimal.valueOf(0)) != 0) {
                int ratio = val1.divide(val2, 2, BigDecimal.ROUND_HALF_UP)
                        .multiply(BigDecimal.valueOf(100.00)).intValue();
                return ratio;
            }
        }
        return null;
    }

}
